package com.blue.waffle.iwc.utils;

import java.sql.SQLException;
import java.util.List;

import com.blue.waffle.iwc.database.SqliteDatabaseHelper;
import com.blue.waffle.iwc.domains.Difficulties;
import com.blue.waffle.iwc.domains.Difficulty;
import com.blue.waffle.iwc.domains.Level;
import com.blue.waffle.iwc.domains.Profile;
import com.blue.waffle.iwc.domains.Word;
import com.blue.waffle.iwc.game.IWCGame;

/**
 * This is a game manager which manages the current user profile and all its
 * associated data in the game.
 * 
 * @author WENBIN
 * 
 */
public class GameManager {

	private IWCGame game;
	private Difficulties difficultyRules;
	private Profile userProfile;

	private List<Level> gameLevels;
	private int currentLevelIndex;

	public IWCGame getGame() {
		return game;
	}
	
	public Difficulties getDifficultyRules() {
		if (difficultyRules==null) {
			if (userProfile!=null) {
				difficultyRules=Difficulties.getDifficulty(userProfile.getCurrentDifficulty().getId());
			}
		}
		return difficultyRules;
	}

	public Profile getUserProfile() {
		if (userProfile == null) {
			List<Profile> profiles;
			try {
				profiles = game.getDatabaseHelper().getProfileHelper()
						.selectAll();

				if (profiles != null && profiles.size() > 0) {
					userProfile = profiles.get(0);
				}
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}

		return userProfile;
	}

	public GameManager setUserProfile(Profile userProfile) {
		this.userProfile = userProfile;
		return this;
	}
	
	public Difficulty getCurrentDifficulty() {
		Profile profile=getUserProfile();
		
		if (profile!=null) {
			if (profile.getCurrentDifficulty().getId()<1) {
				return null;
			}
			
			Difficulty difficulty=profile.getCurrentDifficulty();
			if (difficulty.getName()==null) {
				try {
					profile.setCurrentDifficulty(game.getDatabaseHelper().getDifficultyHelper().selectById(difficulty.getId()));
				} catch (SQLException e) {
					e.printStackTrace();
				}
			}
			return profile.getCurrentDifficulty();
		}
		
		return null;
	}

	/**
	 * Sets the current difficulty, note that it will reset the game levels if a
	 * different difficulty is provided.
	 * 
	 * @param currentDifficulty
	 */
	public GameManager setCurrentDifficulty(Difficulty currentDifficulty) {
		Profile profile=getUserProfile();
		
		if (profile!=null) {
			difficultyRules=null;
			if (gameLevels != null) {
				gameLevels.clear();
			}
			this.userProfile.setCurrentDifficulty(currentDifficulty);
		}
		 
		return this;
	}
	
	public void addUserLevel(final Level level){
		if (level!=null) {
			getUserProfile();
			if (level.isCompleted()) {
				level.setProfile(userProfile);
					new Thread(new Runnable() {
						
						@Override
						public void run() {
							userProfile.setLastPlayedLevel(currentLevelIndex);
							try {
								game.getDatabaseHelper().getProfileLevelHelper().save(level);
								PersistProfile();
							} catch (SQLException e) {
								e.printStackTrace();
							}
							
							
						}
					}).start();
					
			}
			
		}
	}
	
	public Level getNextLevel(){
		Level level=null;
		if (getUserProfile()!=null && getGameLevels()!=null) {
			if (this.userProfile.getNextLevelIndex()<gameLevels.size()) {
				level=getLevel((int)this.userProfile.getNextLevelIndex());
			}
		}
		return level;
	}

	public Level getLevel(int levelIndex) {
		Level level = null;
		try {
			level = getGameLevels().get(levelIndex);
			currentLevelIndex=levelIndex;
			//userProfile.setLastPlayedLevel(levelIndex);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return level;
	}

	public List<Level> getGameLevels() {
		if (gameLevels == null || gameLevels.isEmpty()) {
			List<Level> levels = null;
			try {
				levels = game
						.getDatabaseHelper()
						.getLevelHelper()
						.selectAll(userProfile.getCurrentDifficulty(),
								userProfile.getLevelRandomSeed());
			} catch (SQLException e) {
				e.printStackTrace();
			}
			if (gameLevels == null) {
				gameLevels = levels;
			} else {
				if (levels != null) {
					gameLevels.addAll(levels);
				}
			}
		}
		return gameLevels;
	}
	
	public Word getLevelWord(Level level){
		Word word=null;
		if (level!=null) {
			try {
				word=game.getDatabaseHelper().getWordHelper().findById(level.getWord().getId());
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		return word;
	}

	public GameManager(IWCGame game) {
		this.game = game;
	}

	public void resetDifficulty() {
		if (getUserProfile()!=null) {
			SqliteDatabaseHelper helper=this.game.getDatabaseHelper();
			try {
				userProfile.setLastPlayedLevel(-1);
				userProfile.setLevelRandomSeed(System.currentTimeMillis());
				helper.getProfileHelper().save(userProfile);
				gameLevels=null;
			} catch (SQLException e) {
				e.printStackTrace();
			}
			
		}
	}
	
	public void PersistProfile() throws SQLException {
		if (getUserProfile()!=null) {
			this.game.getDatabaseHelper().getProfileHelper().save(userProfile);
		}
		
	}

}
